home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK1.toast / Development Kits (Disc 1) / QuickDraw 3D / Documentation / d e v e l o p / Develop Issue 23 article / Geometry Sample / Shell src / Application.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-21  |  21.8 KB  |  862 lines  |  [TEXT/MPS ]

  1. #include "BuildControl.h"
  2.  
  3.  
  4. #if defined(qUseDumpFile)
  5.     #include "DumpHeader.h"
  6. #else
  7.     #include <QuickDraw.h>
  8.     #include <Dialogs.h>
  9.     #include <Fonts.h>
  10.     #include <Processes.h>
  11.     #include <TextEdit.h>
  12.     #include <Events.h>
  13.     #include <Menus.h>
  14.     #include <Memory.h>
  15.     #include <Resources.h>
  16.     #include <Errors.h>
  17.     #include <ToolUtils.h>
  18. #endif
  19.  
  20. #include "WindowObj.h"
  21. #include "AESupport.h"
  22. #include "FloatingWindowSupport.h"
  23.  
  24. #include "MainWindow.h"
  25. #include "QuickDraw3DSupport.h"
  26.  
  27. #ifdef __powerc
  28. QDGlobals qd;
  29. #endif
  30.  
  31.  
  32. //
  33. // ••• CHANT THE FOLLOWING LINES EVERY TIME YOU THINK ABOUT CHANGING THIS CODE •••
  34. //
  35. // • This is a barebones shell.
  36. // • This is NOT designed to do everything for everyone.
  37. // • This does not contain the one true way to do anything.
  38. // • This code should err on the side of simplicity and size versus
  39. //   functionality and bloat.
  40. //
  41.  
  42.  
  43. //
  44. // General event handlers/other
  45. //
  46. void InitApplication(void);
  47. void PreEventLoop(void);
  48. void MainEventLoop(void);
  49. void PostEventLoop(void);
  50. void GeneralAdjustMenus(void);
  51. void NotifyWindow(WindowPtr win, long message);
  52. void DoClick(WindowPtr win, EventRecord *event, long message);
  53. void DoAdjustMenus(void);
  54. void DoActivate(WindowPtr win, Boolean activate);
  55. void DoUpdate(WindowPtr thisWindow);
  56. void DoIdle(void);
  57. void DoClose(WindowPtr win);
  58. void DoKeys(long message, short modifiers);
  59. void DoEditMenu(WindowPtr win, short item);
  60. pascal void DoDeviceLoopDraw(short, short, GDHandle, long);
  61. void MenuCommand(long);
  62.  
  63. //
  64. // Specific event handlers for the AboutBox window.
  65. //
  66. void DoAboutBox(void);
  67.  
  68. void AboutBoxDraw(WindowObjHndl obj, short depth);
  69. void AboutBoxClick(WindowObjHndl obj, EventRecord *event, long message);
  70. void AboutBoxActivate(WindowObjHndl obj, Boolean activate);
  71. void AboutBoxKeys(WindowObjHndl obj, long message, short mods);
  72. void AboutBoxNotify(WindowObjHndl obj, long message);
  73.  
  74.  
  75. Boolean gDone;
  76. static Boolean gInBackground;
  77.  
  78.  
  79.  
  80. #pragma segment Main
  81.  
  82. //-----------------------------------------------------------------------
  83. // This will get called whenever there are no windows showing, or the
  84. // frontmost window is someone else's.  Perform menu adjustments 
  85. // accordingly.
  86. //-----------------------------------------------------------------------
  87. void GeneralAdjustMenus(void)
  88. {
  89.     MenuHandle fileMenu = GetMenuHandle(kFileMenu);
  90.  
  91.     if (fileMenu != NULL) {
  92.         DisableItem(fileMenu, kCloseItem);    DisableItem(fileMenu, kOpenItem);
  93.         EnableItem(fileMenu, kNewItem);        EnableItem(fileMenu, kQuitItem);
  94.     }
  95. }
  96.  
  97. //-----------------------------------------------------------------------
  98. // Anything to setup before the event loop? Do it here.
  99. //-----------------------------------------------------------------------
  100. void PreEventLoop(void)
  101. {
  102.     InitAESupport();
  103.     InitQuickDraw3DSupport();
  104. }
  105.  
  106. //-----------------------------------------------------------------------
  107. // Anything to teardown after the event loop? Do it here.
  108. //-----------------------------------------------------------------------
  109. void PostEventLoop(void)
  110. {
  111.     TeardownQuickDraw3DSupport();
  112. }
  113.  
  114. //-----------------------------------------------------------------------
  115.  
  116. void NotifyWindow(WindowPtr win, long message)
  117. {
  118.     WindowObjHndl obj;
  119.  
  120.     if (IsAppWindow(win)) {
  121.         obj = (WindowObjHndl) GetWRefCon(win);
  122.  
  123.         if ((obj != NULL) && ((*obj)->notify != NULL)) {
  124.             //
  125.             // If the message is not an idle message, send it through,
  126.             // or if it is, only send it if the object has an idle task.
  127.             //
  128.             // We do this to minimize the amount of idle time taken by
  129.             // this app.  If we don't implement this type of check, the
  130.             // amount of idle time taken by this app will grow when it
  131.             // really doesn't need to.  If a window needs idle time,
  132.             // it should set the hasIdleTask flag in its ObjHndl.
  133.             //
  134.             if ((message != kIdleNotification) 
  135.             || ((message == kIdleNotification) && ((*obj)->hasIdleTask == true))) {
  136.                 GrafPtr oldPort = SetupPort(win);
  137.                 (*(*obj)->notify)(obj, message);
  138.                 SetPort(oldPort);
  139.             }
  140.         }
  141.     }
  142. }
  143.  
  144. //-----------------------------------------------------------------------
  145. // Walk our window list, and if any window has an idle handler call it.
  146. //
  147. // For most things, you should modify the window's specific idle
  148. // routine instead of touching this.
  149. //-----------------------------------------------------------------------
  150. void DoIdle(void)
  151. {
  152.     WindowPtr    win;
  153.     GrafPtr        oldPort;
  154.     
  155.     GetPort(&oldPort);
  156.  
  157.     for (win = FrontWindow(); win != NULL; 
  158.             win = (WindowPtr) ((WindowPeek) win)->nextWindow) {
  159.         SetPort(win);
  160.         NotifyWindow(win, kIdleNotification);
  161.     }
  162.  
  163.     SetPort(oldPort);
  164. }
  165.  
  166. //-----------------------------------------------------------------------
  167. // Main dispatch routine to the window's activate routine.
  168. //
  169. // For most things, you should modify the window's specific activate
  170. // routine instead of touching this.
  171. //-----------------------------------------------------------------------
  172. void DoActivate(WindowPtr win, Boolean activate)
  173. {
  174.     WindowObjHndl obj = (WindowObjHndl) GetWRefCon(win);
  175.     
  176.     if ((obj != NULL) && ((*obj)->activate != NULL)) {
  177.         GrafPtr    oldPort = SetupPort(win);
  178.         (*(*obj)->activate)(obj, activate);
  179.         SetPort(oldPort);
  180.     }
  181. }
  182.  
  183. //-----------------------------------------------------------------------
  184. // Main dispatch routine to the window's close routine.
  185. //
  186. // For most things, you should modify the window's specific close
  187. // code instead of touching this.
  188. //-----------------------------------------------------------------------
  189. void DoClose(WindowPtr win)
  190. {
  191.     GrafPtr    oldPort = SetupPort(win);
  192.  
  193. #if defined(qFloatingWindowSupport)
  194.     HideThisWindow(win);
  195. #endif
  196.  
  197.     NotifyWindow(win, kCloseNotification);
  198.     SetPort(oldPort);
  199. }
  200.  
  201. //-----------------------------------------------------------------------
  202. // Main dispatch routine to the window's AdjustMenu routine.
  203. //
  204. // For most things, you should modify the window's specific AdjustMenu
  205. // code instead of touching this.
  206. //-----------------------------------------------------------------------
  207. void DoAdjustMenus(void)
  208. {
  209. #if defined (qFloatingWindowSupport)
  210.     WindowPtr win = FrontNonFloatingWindow();
  211. #else
  212.     WindowPtr win = FrontWindow();
  213. #endif
  214.  
  215.     if (IsAppWindow(win))
  216.         NotifyWindow(win, kAdjustMenusNotification);
  217.     else
  218.         //
  219.         // OK, we're probably in a state where there is no
  220.         // window showing, in which case we need to call the
  221.         // GlobalAdjustMenus routine instead.
  222.         //
  223.         GeneralAdjustMenus();
  224. }
  225.  
  226. //-----------------------------------------------------------------------
  227. // Main dispatch routine to the window's click routine.
  228. //
  229. // For most things, you should modify the window's specific click
  230. // routine instead of touching this.
  231. //-----------------------------------------------------------------------
  232. void DoClick(WindowPtr win, EventRecord *event, long message)
  233. {
  234.     WindowObjHndl obj = (WindowObjHndl) GetWRefCon(win);
  235.     
  236.     if ((obj != NULL) && ((*obj)->click != NULL)) {
  237.         GrafPtr    oldPort = SetupPort(win);
  238.         (*(*obj)->click)(obj, event, message);
  239.         SetPort(oldPort);
  240.     }
  241. }
  242.  
  243. //-----------------------------------------------------------------------
  244. // If we received a non-command key event, pass it to the window if
  245. // it wants to handle it.
  246. //
  247. // For most things, you should modify the window's specific keys
  248. // routine instead of touching this.
  249. //-----------------------------------------------------------------------
  250. void DoKeys(long message, short modifiers)
  251. {
  252.     WindowPtr win = FrontNonFloatingWindow();
  253.     
  254.     if (IsAppWindow(win)) {
  255.         WindowObjHndl obj = (WindowObjHndl) GetWRefCon(win);
  256.         
  257.         if ((obj != NULL) && ((*obj)->keys != NULL)) {
  258.             GrafPtr    oldPort = SetupPort(win);
  259.             (*(*obj)->keys)(obj, message, modifiers);
  260.             SetPort(oldPort);
  261.         }
  262.     }
  263. }
  264.  
  265. //-----------------------------------------------------------------------
  266. // Main dispatch routine to the window's click routine.
  267. //
  268. // For most things, you should modify the window's specific update
  269. // routine instead of touching this.
  270. //-----------------------------------------------------------------------
  271. void DoUpdate(WindowPtr win)
  272. {
  273.     static DeviceLoopDrawingUPP    drawProc = NULL;
  274.  
  275.     check(win != NULL);
  276.     SetPort(win);
  277.  
  278.     if (drawProc == NULL)
  279.         drawProc = NewDeviceLoopDrawingProc(DoDeviceLoopDraw);    
  280.     
  281.     BeginUpdate(win);
  282.     DeviceLoop(win->visRgn, drawProc, (long) win, singleDevices);
  283.     EndUpdate(win);
  284. }
  285.  
  286. //-----------------------------------------------------------------------
  287. // Main dispatch routine to the window's edit code
  288. //
  289. // For most things, you should modify the window's specific edit
  290. // notification handler instead of touching this.
  291. //
  292. // Why aren't we just sending the raw menu item to the window?
  293. // Because we want to separate the act of editing the window using 
  294. // common menu commands from the menu items.  This will make life
  295. // easier down the road if we make this scriptable.
  296. //-----------------------------------------------------------------------
  297. void DoEditMenu(WindowPtr win, short item)
  298. {
  299.     long     message;
  300.  
  301.     if (IsAppWindow(win)) {
  302.         switch (item) {
  303.             case kUndoItem:        message = kUndoNotification;         break;
  304.             case kCutItem:        message = kCutNotification;         break;
  305.             case kCopyItem:        message = kCopyNotification;         break;
  306.             case kPasteItem:    message = kPasteNotification;         break;
  307.             case kClearItem:    message = kClearNotification;         break;
  308.             case kSelectAllItem:message = kSelectAllNotification;    break;
  309.         }
  310.         NotifyWindow(win, message);
  311.     }
  312. }
  313.  
  314. //-----------------------------------------------------------------------
  315. // This is bit nicer interface than DeviceLoop's drawing proc (and it
  316. // sets thePort for all windows about to be drawn to.)
  317. //
  318. // For most things, you should modify the window's specific update
  319. // routine instead of touching this.
  320. //-----------------------------------------------------------------------
  321. pascal void DoDeviceLoopDraw(    short        pixelDepth,
  322.                                 short         dFlags,
  323.                                 GDHandle    theDevice,
  324.                                 long        theWin)
  325. {
  326. #pragma unused (dFlags, theDevice)
  327.     GrafPtr            oldPort;
  328.     WindowPtr        win = (WindowPtr) theWin;
  329.     WindowObjHndl     obj;
  330.  
  331.     oldPort = SetupPort(win);
  332.     obj = (WindowObjHndl) GetWRefCon(win);
  333.     
  334.     if ((obj != NULL) && ((*obj)->draw != NULL))
  335.         (*(*obj)->draw)(obj, pixelDepth);
  336.  
  337.     SetPort(oldPort);
  338. }
  339.  
  340. //-----------------------------------------------------------------------
  341. // Put up the window, allocate the window data and set its fields
  342. //-----------------------------------------------------------------------
  343. WindowObjHndl NewObjWindow(    short                windID,
  344.                             OSType                type,
  345.                             Boolean                itFloats,
  346.                             Boolean                hasIdleTask,
  347.                             DrawContentProcPtr    draw,
  348.                             KeystrokeProcPtr    keys,
  349.                             ClickProcPtr        click,
  350.                             ActivateProcPtr        activate,
  351.                             NotifyProcPtr        notify)
  352. {
  353.     WindowPtr        win, listPosition = NULL;
  354.     WindowObjPtr    objPtr;
  355.     WindowObjHndl    obj;
  356.     GrafPtr            oldPort;
  357.  
  358.     if (itFloats)    listPosition = (WindowPtr) -1;
  359.     obj = NULL;
  360.     win = GetNewCWindow(windID, NULL, listPosition);
  361.     check(win != NULL);
  362.  
  363.     if (win != NULL) {        
  364.         obj = (WindowObjHndl) NewHandle(sizeof(WindowObj));
  365.  
  366.         if (obj != NULL) {
  367.             objPtr = *obj;
  368.             objPtr->type         = type;
  369.             objPtr->hasIdleTask    = hasIdleTask;
  370.             objPtr->draw         = draw;
  371.             objPtr->keys         = keys;
  372.             objPtr->notify         = notify;
  373.             objPtr->activate     = activate;
  374.             objPtr->click         = click;
  375.             objPtr->window         = win;
  376.             objPtr->refCon         = 0UL;
  377.         }
  378.         // 
  379.         // Put in those things that make our windows special..
  380.         // And call the windows's create routine if there is one.
  381.         //
  382.         if (itFloats)
  383.             ((WindowPeek) win)->windowKind = kApplicationFloaterKind;
  384.         else
  385.             ((WindowPeek) win)->windowKind = kAppWindowKind;
  386.         SetWRefCon(win, (long) obj);
  387.  
  388.         oldPort = SetupPort(win);
  389.         NotifyWindow(win, kCreateNotification);
  390.  
  391.         //
  392.         // Call this after the refCon has been set, and after the
  393.         // windowKind is set up so we can figure out what kind of window
  394.         // this is from the PutInList call below.
  395.         //
  396.         // The create proc should set the window kind properly so this
  397.         // all works..
  398.         //
  399. #if defined(qFloatingWindowSupport)
  400.         if (!IsFloatingWindow(win))
  401.             PutNonFloatingWindowInList(win, (WindowPtr) -1);
  402.     
  403.         ShowThisWindow(win);
  404.         SelectThisWindow(win);
  405. #endif
  406.  
  407.         SetPort(oldPort);
  408.     }
  409.     return obj;
  410. }
  411.  
  412. //-----------------------------------------------------------------------
  413.  
  414. void DisposeObjWindow(WindowObjHndl obj)
  415. {
  416.     WindowPtr win = (*obj)->window;
  417.     GrafPtr    oldPort;
  418.     
  419.     check(win != NULL);
  420.     //
  421.     // Call the windows's destroy routine if there is one
  422.     //
  423.  
  424.     oldPort = SetupPort(win);
  425.     NotifyWindow(win, kDestroyNotification);
  426.     HideThisWindow(win);
  427.     SetPort(oldPort);
  428.     DisposeWindow(win);
  429. }
  430.  
  431. //-----------------------------------------------------------------------
  432.  
  433. void InitApplication(void)
  434. {
  435.     Handle theMenu;
  436.  
  437.     MaxApplZone();
  438.     InitGraf(&qd.thePort);
  439.     InitFonts();
  440.     InitWindows();
  441.     InitMenus();
  442.     TEInit();
  443.     InitDialogs(NULL);
  444.     InitCursor();
  445.     FlushEvents(0, everyEvent);
  446.     
  447.     gInBackground = gDone = false;
  448.     theMenu = GetNewMBar(128);
  449.  
  450.     if (theMenu != NULL) {
  451.         SetMenuBar(theMenu);
  452.         AddResMenu(GetMHandle(128), 'DRVR');
  453.         DrawMenuBar();
  454.     }
  455.     else {
  456.         DebugStr("\pError loading the menus.  Missing resource file?");
  457.         gDone = true;
  458.     }
  459. }
  460.  
  461. //-----------------------------------------------------------------------
  462.  
  463. void MainEventLoop(void)
  464. {
  465.     EventRecord        event;
  466.     WindowPtr        win;
  467.     short            clickArea;
  468.     Rect            screenRect;
  469.     long            result;
  470.     char            charCode;
  471.  
  472.     while (!gDone) {
  473.         if (WaitNextEvent(everyEvent, &event, 60, NULL)) {
  474.             switch (event.what) {
  475.                 case mouseDown:
  476.                     clickArea = FindWindow(event.where, &win);
  477.                     
  478.                     switch(clickArea) {
  479.                         case inDrag:
  480.                             screenRect = (**GetGrayRgn()).rgnBBox;
  481. #if defined(qFloatingWindowSupport)
  482.                             DragThisWindow(win, event.where, &screenRect);                            break;
  483. #else
  484.                             DragWindow(win, event.where, &screenRect);
  485. #endif                
  486.                         case inContent:
  487. #if defined(qFloatingWindowSupport)
  488.                             if (NeedsSelect(win))
  489.                                 SelectThisWindow(win);
  490. #else
  491.                             if (win != FrontWindow())
  492.                                 SelectWindow(win);
  493. #endif
  494.                             else
  495.                                 DoClick(win, &event, (long) clickArea);
  496.                             break;
  497.                             
  498.                         case inGoAway:
  499.                             if ((IsAppWindow(win)) && (TrackGoAway(win, event.where)))
  500.                                 DoClose(win);
  501.                             break;
  502.                         
  503.                         case inMenuBar:
  504.                             DoAdjustMenus();
  505.                             result = MenuSelect(event.where);
  506.                             if ((result >> 16) != 0) MenuCommand(result);
  507.                             break;
  508.         
  509.                         case inSysWindow:
  510.                             SystemClick(&event, win);
  511.                             break;
  512.  
  513.                         case inGrow:
  514.                             DoClick(win, &event, (long) clickArea);
  515.                             break;
  516.  
  517.                         default:
  518.                             break;
  519.                     }
  520.                     break;
  521.         
  522.                 case keyDown:
  523.                     charCode = event.message & charCodeMask;
  524.     
  525.                     if ((event.modifiers & cmdKey) != 0) {    
  526.                         DoAdjustMenus();
  527.                         result = MenuKey(charCode);
  528.                         if ((result >> 16) != 0) MenuCommand(result);
  529.                     }
  530.                     else
  531.                         DoKeys(event.message, event.modifiers);
  532.                     break;
  533.                     
  534.                 case updateEvt:
  535.                     win = (WindowPtr) event.message;    
  536.                     DoUpdate(win);
  537.                     break;
  538.                 
  539.                 case activateEvt:
  540.                     win = (WindowPtr) event.message;
  541.                     DoActivate(win, (event.modifiers & activeFlag) != 0);
  542.                     break;
  543.                 
  544.                 case osEvt:
  545.                     if (event.message & 0x01000000) {
  546.                         gInBackground = !gInBackground;
  547. #if defined(qFloatingWindowSupport)
  548.                         if (gInBackground)
  549.                             SuspendFloaters();
  550.                         else
  551.                             ResumeFloaters();
  552. #else
  553.                         win = FrontWindow();
  554.                         if (IsAppWindow(win))
  555.                             DoActivate(win, !gInBackground);
  556. #endif
  557.                     }
  558.             }
  559.         }
  560.         else
  561.             DoIdle();
  562.     }
  563. }
  564.  
  565. //-----------------------------------------------------------------------
  566.  
  567. void MenuCommand(long whaHappened)
  568. {
  569.     short        menuID, menuItem;
  570.     WindowPtr     win = FrontNonFloatingWindow();
  571.     extern void OpenFloatWindow(void);
  572.  
  573.     menuID = (whaHappened >> 16);
  574.     menuItem = (whaHappened & 0xFFFF);
  575.     
  576.     switch (menuID) {
  577.         case kAppleMenu:
  578.             if (menuItem == kAboutItem) DoAboutBox();
  579.             break;
  580.  
  581.         case kFileMenu:
  582.             switch (menuItem) {
  583.                 case kNewItem:
  584.                     (void) NewObjWindow(128, 'Main', false, true, MainWindowDraw, 
  585.                                 MainWindowKeys, MainWindowClick, NULL, 
  586.                                 MainWindowNotify);
  587.                     break;
  588.     
  589.                 case kOpenItem:
  590.                     OpenFloatWindow();
  591.                     break;            
  592.     
  593.                 case kCloseItem:
  594.                     if (IsAppWindow(win))
  595.                         DoClose(win);
  596.                     break;            
  597.                 case kQuitItem:
  598.                     gDone = true;
  599.                     break;            
  600.             }
  601.             break;
  602.  
  603.         case kEditMenu:
  604.             DoEditMenu(win, menuItem);
  605.             break;
  606.     }
  607.     HiliteMenu(0);
  608. }
  609.  
  610. //-----------------------------------------------------------------------
  611.  
  612. Boolean IsAppWindow(WindowPtr win)
  613. {
  614.     Boolean oneOfOurs = false;
  615.     
  616.     if ((win != NULL) 
  617. #if defined (qFloatingWindowSupport)
  618.         && ((((WindowPeek) win)->windowKind == kAppWindowKind)
  619.             || (IsFloatingWindow(win) == true)))
  620. #else
  621.         && (((WindowPeek) win)->windowKind == kAppWindowKind))
  622. #endif
  623.         oneOfOurs = true;
  624.  
  625.     return oneOfOurs;
  626. }
  627.  
  628. //-----------------------------------------------------------------------
  629.  
  630. GrafPtr SetupPort(GrafPtr port)
  631. {
  632.     GrafPtr oldPort;
  633.     
  634.     check(port != NULL);
  635.     GetPort(&oldPort);
  636.     if (oldPort != port) SetPort(port);
  637.     return oldPort;
  638. }
  639.  
  640. //-----------------------------------------------------------------------
  641.  
  642. void main(void)
  643. {
  644.     InitApplication();
  645.     PreEventLoop();
  646.     MainEventLoop();
  647.     PostEventLoop();
  648. }
  649.  
  650. //-----------------------------------------------------------------------
  651.  
  652. void pstrcat(Str255 frontStr, ConstStr255Param backStr)
  653. {
  654.     short    backLength = backStr[0];
  655.  
  656.     if (frontStr[0] + backLength > 255)
  657.         backLength = 255 - frontStr[0];
  658.  
  659.     BlockMoveData(&backStr[1], &frontStr[frontStr[0] + 1], backLength);
  660.     frontStr[0] += backLength;    
  661. }
  662.  
  663. //-----------------------------------------------------------------------
  664.  
  665. void pstrcpy(void *src, void *dest)
  666. {
  667.     BlockMoveData(src, dest,(*(Str255 *)src)[0] + 1);
  668. }
  669.  
  670.  
  671. #pragma segment AboutBox
  672. //-----------------------------------------------------------------------
  673. // •• ABOUTBOX WINDOW ••
  674. //-----------------------------------------------------------------------
  675.  
  676. static WindowObjHndl pAboutBox = NULL;
  677.     
  678.  
  679. //-----------------------------------------------------------------------
  680.  
  681. void DoAboutBox(void)
  682. {
  683.     if (pAboutBox == NULL)
  684.         pAboutBox = NewObjWindow(129, 'Abot', false, false, AboutBoxDraw, AboutBoxKeys,
  685.                             AboutBoxClick, AboutBoxActivate, AboutBoxNotify);
  686.     else {
  687.         ShowThisWindow((*pAboutBox)->window);
  688.         SelectThisWindow((*pAboutBox)->window);
  689.     }
  690. }
  691.  
  692. //-----------------------------------------------------------------------
  693.  
  694. void DisableAllMenuItems(MenuHandle menu)
  695. {
  696.     short     index, count = CountMItems(menu);
  697.  
  698.     for (index = 1; index <= count; index ++)
  699.         DisableItem(menu, index);
  700. }
  701.  
  702. //-----------------------------------------------------------------------
  703.  
  704. void EnableAllMenuItems(MenuHandle menu)
  705. {
  706.     short     index, count = CountMItems(menu);
  707.  
  708.     for (index = 1; index <= count; index ++)
  709.         EnableItem(menu, index);
  710. }
  711.  
  712. //-----------------------------------------------------------------------
  713.  
  714. void AboutBoxNotify(WindowObjHndl obj, long message)
  715. {
  716.     ControlHandle    cntl;
  717.     WindowPtr        win = (*obj)->window;
  718.     Rect            rct;
  719.  
  720.     switch (message) {
  721.         case kCloseNotification:
  722.             break;
  723.  
  724.         case kCreateNotification:
  725.             TextFont(systemFont);
  726.             TextSize(12);
  727.             rct = win->portRect;
  728.             SetRect(&rct, rct.right - 100, rct.bottom - 35, 
  729.                     rct.right - 20, rct.bottom - 15);    
  730.             cntl = NewControl(win, &rct, "\pOK", true, 0, 0, 1, pushButProc, 0);
  731.             (*obj)->refCon = (unsigned long) cntl;
  732.             break;
  733.         
  734.         case kDestroyNotification:
  735.             cntl = (ControlHandle) (*obj)->refCon;
  736.             
  737.             if (cntl != NULL) DisposeControl(cntl);
  738.             break;
  739.         
  740.         case kAdjustMenusNotification: {
  741.                 MenuHandle     fileMenu = GetMenuHandle(kFileMenu);
  742.                 MenuHandle     editMenu = GetMenuHandle(kEditMenu);
  743.  
  744.                 if (fileMenu != NULL) {
  745.                     EnableAllMenuItems(fileMenu);
  746.  
  747.                     EnableItem(fileMenu, kCloseItem);
  748.                     DisableItem(fileMenu, kNewItem);
  749.                     DisableItem(fileMenu, kOpenItem);
  750.                 }
  751.                 
  752.                 if (editMenu != NULL)
  753.                     DisableAllMenuItems(editMenu);
  754.             }
  755.             break;
  756.     }    
  757. }
  758.  
  759. //-----------------------------------------------------------------------
  760.  
  761. void AboutBoxDraw(WindowObjHndl obj, short depth)
  762. {
  763. #pragma unused (depth)
  764.     Rect            rct, box;
  765.     WindowPtr        win = (*obj)->window,
  766. #if defined(qFloatingWindowSupport)
  767.                     front = FrontNonFloatingWindow();
  768. #else
  769.                     front = FrontWindow();
  770. #endif
  771.     Handle            text;
  772.     Size            textSize;    
  773.     ControlHandle    cntl = (ControlHandle) (*obj)->refCon;
  774.     short            hiliteVal;
  775.  
  776.     check(cntl != NULL);
  777.     PenNormal();
  778.  
  779.     if ((gInBackground == true) || (front != win)) {
  780.         RGBColor rgb = {0x7fff, 0x7fff, 0x7fff};
  781.         RGBForeColor(&rgb);
  782.         hiliteVal = 255;    
  783.     }
  784.     else {
  785.         ForeColor(blackColor);
  786.         hiliteVal = 0;
  787.     }
  788.  
  789.     HiliteControl(cntl, hiliteVal);
  790.     DrawControls(win);
  791.     rct = (*(ControlHandle) (*obj)->refCon)->contrlRect;
  792.     PenSize(3, 3);
  793.     InsetRect(&rct, -4, -4);
  794.     FrameRoundRect(&rct, 16, 16);
  795.     text = Get1Resource('TEXT', 128);
  796.  
  797.     if (text != NULL) {
  798.         textSize = GetHandleSize(text);
  799.         box = win->portRect;
  800.         InsetRect(&box, 15, 10);
  801.         box.bottom -= 45;
  802.         HLock(text);
  803.         TextBox(*text, textSize, &box, teForceLeft);
  804.         HUnlock(text);
  805.     }
  806. }
  807.  
  808. //-----------------------------------------------------------------------
  809.  
  810. void AboutBoxClick(WindowObjHndl obj, EventRecord *event, long message)
  811. {
  812.     ControlHandle    button;
  813.     short            part;
  814.     WindowPtr        win = (*obj)->window;
  815.     Point            localPt;
  816.  
  817.     if (message == inContent) {
  818.         localPt = event->where;
  819.         GlobalToLocal(&localPt);
  820.     
  821.         part = FindControl(localPt, win, &button);
  822.         
  823.         if ((part == inButton) && (button != NULL))
  824.             if (TrackControl(button, event->where, NULL) != 0)
  825.                 HideThisWindow(win);
  826.     }
  827. }
  828.  
  829. //-----------------------------------------------------------------------
  830. // If the user hit enter, fake an 'OK' hilite and hide the window.
  831. //-----------------------------------------------------------------------
  832. void AboutBoxKeys(WindowObjHndl obj, long message, short mods)
  833. {
  834. #pragma unused (mods)
  835.     unsigned char    code;
  836.     ControlHandle    button;
  837.     long            dontCare;
  838.  
  839.     code = (message & keyCodeMask) >> 8;
  840.  
  841.     if ((code == 0x24) || (code == 0x4C)) {
  842.         button = (ControlHandle) (*obj)->refCon;
  843.  
  844.         if (button != NULL) {
  845.             HiliteControl(button, true);
  846.             Delay(8, &dontCare);
  847.             HiliteControl(button, false);
  848.         }
  849.         HideThisWindow((*obj)->window);
  850.     }
  851. }
  852.  
  853. //-----------------------------------------------------------------------
  854. // All the drawing is done in the update proc, so just invalidate the
  855. // whole window to force a complete redraw.
  856. //-----------------------------------------------------------------------
  857. void AboutBoxActivate(WindowObjHndl obj, Boolean activate)
  858. {
  859. #pragma unused (activate)
  860.     
  861.     InvalRect(&(*obj)->window->portRect);
  862. }